package com.csg.service.entity;

import com.google.common.collect.Sets;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.util.StringUtils;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

/**
 * @author george
 */
@Data
public class Client implements ClientDetails {

    private String clientId;
    private String clientSecret;
    private Set<String> scope;
    private Set<String> resourceIds;
    private Set<String> authorizedGrantTypes;
    private Set<String> registeredRedirectUris;
    private Set<String> autoApproveScopes;
    private Set<Role> roles;
    private Integer accessTokenValiditySeconds;
    private Integer refreshTokenValiditySeconds;
    private Map<String, Object> additionalInformation;

    public Client() {
    }

    public Client(String clientId,
                  String clientSecret,
                  String scope,
                  String resourceIds,
                  String authorizedGrantTypes,
                  String registeredRedirectUris,
                  String autoApproveScopes,
                  Set<Role> roles,
                  Integer accessTokenValiditySeconds,
                  Integer refreshTokenValiditySeconds) {
        this(clientId, clientSecret, scope, resourceIds, authorizedGrantTypes, registeredRedirectUris, autoApproveScopes, roles, accessTokenValiditySeconds, refreshTokenValiditySeconds, null);
    }

    public Client(String clientId,
                  String clientSecret,
                  String scope,
                  String resourceIds,
                  String authorizedGrantTypes,
                  String registeredRedirectUris,
                  String autoApproveScopes,
                  Set<Role> roles,
                  Integer accessTokenValiditySeconds,
                  Integer refreshTokenValiditySeconds,
                  Map<String, Object> additionalInformation) {
        this.clientId = clientId;
        this.clientSecret = clientSecret;
        this.scope = StringUtils.commaDelimitedListToSet(scope);
        this.resourceIds = StringUtils.commaDelimitedListToSet(resourceIds);
        this.authorizedGrantTypes = StringUtils.commaDelimitedListToSet(authorizedGrantTypes);
        this.registeredRedirectUris = StringUtils.commaDelimitedListToSet(registeredRedirectUris);
        this.autoApproveScopes = StringUtils.commaDelimitedListToSet(autoApproveScopes);
        this.roles = roles;
        this.accessTokenValiditySeconds = accessTokenValiditySeconds;
        this.refreshTokenValiditySeconds = refreshTokenValiditySeconds;
        this.additionalInformation = additionalInformation;
    }

    @Override
    public boolean isSecretRequired() {
        return this.clientSecret != null;
    }

    @Override
    public boolean isScoped() {
        return this.scope != null && !this.scope.isEmpty();
    }

    @Override
    public Set<String> getRegisteredRedirectUri() {
        return registeredRedirectUris;
    }

    @Override
    public Collection<GrantedAuthority> getAuthorities() {
        Collection<GrantedAuthority> grantedAuthorities = Sets.newHashSet();
        grantedAuthorities.addAll(roles);
        return grantedAuthorities;
    }

    @Override
    public boolean isAutoApprove(String scope) {
        if (autoApproveScopes == null) {
            return false;
        }
        for (String auto : autoApproveScopes) {
            if ("true".equalsIgnoreCase(auto) || scope.matches(auto)) {
                return true;
            }
        }
        return false;
    }
}
